/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.web.captcha.support;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vacoor.nothing.web.captcha.ImageCaptchaValidationScheduler;
import org.vacoor.nothing.web.captcha.ValidatingImageCaptchaService;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;


/**
 * SessionValidationScheduler implementation that uses a
 * {@link ScheduledExecutorService} to call {@link ValidatingImageCaptchaService#validateCaptchas()} ()} every
 * <em>{@link #getInterval interval}</em> milliseconds.
 */
public class SimpleImageCaptchaValidationScheduler implements ImageCaptchaValidationScheduler, Runnable {
    private static final Logger LOG = LoggerFactory.getLogger(SimpleImageCaptchaValidationScheduler.class);

    ValidatingImageCaptchaService imageCaptchaService;
    private ScheduledExecutorService service;
    private long interval = 0;//DefaultSessionManager.DEFAULT_SESSION_VALIDATION_INTERVAL;
    private boolean enabled = false;

    public SimpleImageCaptchaValidationScheduler() {
    }

    public SimpleImageCaptchaValidationScheduler(ValidatingImageCaptchaService imageCaptchaService) {
        this.imageCaptchaService = imageCaptchaService;
    }

    public ValidatingImageCaptchaService getImageCaptchaService() {
        return imageCaptchaService;
    }

    public void setImageCaptchaService(ValidatingImageCaptchaService imageCaptchaService) {
        this.imageCaptchaService = imageCaptchaService;
    }

    public long getInterval() {
        return interval;
    }

    public void setInterval(long interval) {
        this.interval = interval;
    }

    public boolean isEnabled() {
        return this.enabled;
    }

    /**
     * Creates a single thread {@link ScheduledExecutorService} to validate sessions at fixed intervals
     * and enables this scheduler. The executor is created as a daemon thread to allow JVM to shut down
     */
    //TODO Implement an integration test to test for jvm exit as part of the standalone example
    // (so we don't have to change the unit test execution model for the core module)
    @Override
    public void enableCaptchaValidation() {
        if (this.interval > 0l) {
            this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
                public Thread newThread(Runnable r) {
                    Thread thread = new Thread(r);
                    thread.setDaemon(true);
                    return thread;
                }
            });
            this.service.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS);
            this.enabled = true;
        }
    }

    public void run() {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Executing session validation...");
        }

        long startTime = System.currentTimeMillis();
        this.imageCaptchaService.validateCaptchas();
        long stopTime = System.currentTimeMillis();

        if (LOG.isDebugEnabled()) {
            LOG.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds.");
        }
    }

    @Override
    public void disableCaptchaValidation() {
        this.service.shutdownNow();
        this.enabled = false;
    }
}
